package cn.chinaunicom.mini.program.dingtalk.openapi.service;

import com.alibaba.fastjson2.JSON;
import org.springframework.stereotype.Component;

import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.request.OapiMessageCorpconversationRecallRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationSendbytemplateRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationStatusBarUpdateRequest;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.dingtalk.api.response.OapiMessageCorpconversationRecallResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationSendbytemplateResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationStatusBarUpdateResponse;
import com.taobao.api.ApiException;

import cn.chinaunicom.mini.program.dingtalk.openapi.client.IDingTalkClient;
import cn.chinaunicom.mini.program.dingtalk.openapi.model.enums.BarStatus;
import cn.chinaunicom.mini.program.dingtalk.openapi.model.enums.DingTalkMsgType;
import lombok.extern.slf4j.Slf4j;

/**
 * @ProjectName: dingtalk-adapter
 * @Package: cn.chinaunicom.mini.program.dingtalk.openapi.service
 * @ClassName: DingTalkWorkNoticeAPI
 * @Description: 钉钉工作通知API
 * @Author: wangjc
 * @CreateDate: 2024/6/18
 * @UpdateUser: wangjc
 * @UpdateDate: 2024/6/18
 * @UpdateRemark: 更新内容
 * @Version: 1.0
 */
@Slf4j
@Component
public class DingTalkWorkNoticeAPI {

	public OapiMessageCorpconversationAsyncsendV2Response sendTextMsg(
			OapiMessageCorpconversationAsyncsendV2Request request, String content, String accessToken) throws ApiException {
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype(DingTalkMsgType.MSG_TEXT.getType());
		msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
		msg.getText().setContent(content);
		return sendMessage(request, msg, accessToken);
	}

	public OapiMessageCorpconversationAsyncsendV2Response sendVoiceMsg(
			OapiMessageCorpconversationAsyncsendV2Request request, String mediaId, String accessToken) throws ApiException {
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype(DingTalkMsgType.MSG_VOICE.getType());
		msg.setVoice(new OapiMessageCorpconversationAsyncsendV2Request.Voice());
		msg.getVoice().setMediaId(mediaId);
		return sendMessage(request, msg, accessToken);
	}

	public OapiMessageCorpconversationAsyncsendV2Response sendImageMsg(
			OapiMessageCorpconversationAsyncsendV2Request request, String mediaId, String accessToken) throws ApiException {
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype(DingTalkMsgType.MSG_IMAGE.getType());
		msg.setImage(new OapiMessageCorpconversationAsyncsendV2Request.Image());
		msg.getImage().setMediaId(mediaId);
		return sendMessage(request, msg, accessToken);
	}

	public OapiMessageCorpconversationAsyncsendV2Response sendFileMsg(
			OapiMessageCorpconversationAsyncsendV2Request request, String mediaId, String accessToken) throws ApiException {
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype(DingTalkMsgType.MSG_FILE.getType());
		msg.setFile(new OapiMessageCorpconversationAsyncsendV2Request.File());
		msg.getFile().setMediaId(mediaId);
		return sendMessage(request, msg, accessToken);
	}

	public OapiMessageCorpconversationAsyncsendV2Response sendMarkdownMsg(
			OapiMessageCorpconversationAsyncsendV2Request request, String title, String content, String accessToken) throws ApiException {
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype(DingTalkMsgType.MSG_MARKDOWN.getType());
		msg.setMarkdown(new OapiMessageCorpconversationAsyncsendV2Request.Markdown());
		msg.getMarkdown().setTitle(title);
		msg.getMarkdown().setText(content);
		return sendMessage(request, msg, accessToken);
	}

	public OapiMessageCorpconversationAsyncsendV2Response sendActionCardMsg(
			OapiMessageCorpconversationAsyncsendV2Request request, String title, String markdownContent,
			String singleTitle, String singleUrl, String accessToken) throws ApiException {
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype(DingTalkMsgType.MSG_ACTION_CARD.getType());
		msg.setActionCard(new OapiMessageCorpconversationAsyncsendV2Request.ActionCard());
		msg.getActionCard().setTitle(title);
		msg.getActionCard().setMarkdown(markdownContent);
		msg.getActionCard().setSingleTitle(singleTitle);
		msg.getActionCard().setSingleUrl(singleUrl);
		return sendMessage(request, msg, accessToken);
	}

	public OapiMessageCorpconversationAsyncsendV2Response sendLinkMsg(
			OapiMessageCorpconversationAsyncsendV2Request request, String title, String content, String picMiediaId,
			String messageUrl, String accessToken) throws ApiException {
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype(DingTalkMsgType.MSG_LINK.getType());
		msg.setLink(new OapiMessageCorpconversationAsyncsendV2Request.Link());
		msg.getLink().setTitle(title);
		msg.getLink().setText(content);
		msg.getLink().setPicUrl(picMiediaId);
		msg.getLink().setMessageUrl(messageUrl);
		return sendMessage(request, msg, accessToken);
	}

	public OapiMessageCorpconversationAsyncsendV2Response sendOaMsg(
			OapiMessageCorpconversationAsyncsendV2Request request,
			OapiMessageCorpconversationAsyncsendV2Request.Head head,
			OapiMessageCorpconversationAsyncsendV2Request.Body body, String accessToken) throws ApiException {
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype(DingTalkMsgType.MSG_OA.getType());
		msg.setOa(new OapiMessageCorpconversationAsyncsendV2Request.OA());
		msg.getOa().setHead(head);
		msg.getOa().setBody(body);
		return sendMessage(request, msg, accessToken);
	}

	/**
	 * 发送模板消息给企业内部成员或外部联系人。
	 *
	 * 通过调用钉钉开放平台的接口，使用指定的模板发送消息。此方法封装了消息发送的过程，
	 * 包括构建请求、发送请求和处理响应。
	 *
	 * @param request 发送消息的请求对象，包含消息模板的相关信息和接收者等。
	 * @param accessToken 钉钉接口访问的令牌，用于身份验证。
	 * @return 返回发送消息后的响应对象，包含接口调用的结果信息。
	 * @throws ApiException 如果接口调用过程中出现错误，会抛出此异常。
	 */
	public OapiMessageCorpconversationSendbytemplateResponse sendTemplateMsg(
	        OapiMessageCorpconversationSendbytemplateRequest request, String accessToken) throws ApiException {
	    // 执行接口调用，发送模板消息，并传入接口URL、请求对象和访问令牌
	    OapiMessageCorpconversationSendbytemplateResponse rsp = IDingTalkClient.execute(
	            "https://oapi.dingtalk.com/topapi/message/corpconversation/sendbytemplate", request, accessToken);

	    // 记录消息发送成功的日志
		log.debug("钉钉开放平台接口响应体：{}", JSON.toJSONString(rsp.getBody()));

	    // 返回发送消息后的响应对象
	    return rsp;
	}

	/**
	 * 召回企业内部消息的函数。 该函数用于向钉钉发送请求，以召回之前发送的企业内部消息。
	 *
	 * @param req 召回消息的请求参数，包含需要召回的消息的相关信息。
	 * @return 返回钉钉平台对于消息召回请求的响应。
	 * @throws ApiException 如果钉钉平台返回错误，将抛出此异常。
	 */
	public OapiMessageCorpconversationRecallResponse recallMessage(OapiMessageCorpconversationRecallRequest req,
			String accessToken) throws ApiException {
		// 执行消息召回请求，通过钉钉开放平台的客户端发送请求到指定的URL，并传入请求参数。
		OapiMessageCorpconversationRecallResponse rsp = IDingTalkClient
				.execute("https://oapi.dingtalk.com/topapi/message/corpconversation/recall", req, accessToken);
		// 打印召回消息的响应体，用于调试和日志记录。
		log.debug("钉钉开放平台接口响应体：{}", JSON.toJSONString(rsp.getBody()));
		// 返回召回消息的响应，包含召回操作的结果信息。
		return rsp;
	}

	/**
	 * 审批状态颜色参考 已同意 0xFF78C06E 已拒绝 0xFFF65E5E 已撤销 0xFF858E99 待审批 0xFFFF9D46
	 */
	public OapiMessageCorpconversationStatusBarUpdateResponse updateBarStatus(Long agentId, Long taskId,
			BarStatus status, String accessToken) throws ApiException {
		OapiMessageCorpconversationStatusBarUpdateRequest request = new OapiMessageCorpconversationStatusBarUpdateRequest();
		request.setAgentId(agentId);
		request.setStatusBg(status.getBgColor());
		request.setStatusValue(status.getName());
		request.setTaskId(taskId);
		OapiMessageCorpconversationStatusBarUpdateResponse response = IDingTalkClient.execute(
				"https://oapi.dingtalk.com/topapi/message/corpconversation/status_bar/update", request, accessToken);
		return response;
	}

	/**
	 * 发送钉钉消息的异步接口调用方法。
	 * 该方法通过钉钉开放平台的API发送消息给指定的企业内部成员或群组。
	 * 使用异步发送方式，适用于发送大量消息或需要高效发送场景。
	 *
	 * @param request 发送消息的请求对象，包含消息的接收者等信息。
	 * @param msg 消息内容对象，定义了消息的具体内容和类型。
	 * @param accessToken 钉钉接口访问的令牌，用于身份验证。
	 * @return 返回钉钉接口的响应对象，包含消息发送的结果信息。
	 * @throws ApiException 如果接口调用失败，会抛出ApiException。
	 */
	private OapiMessageCorpconversationAsyncsendV2Response sendMessage(
	        OapiMessageCorpconversationAsyncsendV2Request request,
	        OapiMessageCorpconversationAsyncsendV2Request.Msg msg, String accessToken) throws ApiException {
	    // 设置消息内容
	    request.setMsg(msg);
	    // 执行消息发送请求，通过钉钉开放平台的URL和访问令牌来发送消息
	    OapiMessageCorpconversationAsyncsendV2Response response = IDingTalkClient.execute(
	            "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2", request, accessToken);
	    // 记录消息发送成功的日志
	    log.info("发送消息成功: {}", response);
	    // 返回消息发送的结果
	    return response;
	}
}
